<?php
/*
 * ePublish -- Library for converting website content to ebook format.
 * Copyright (c) 2010 Neilin Chakrabarty : epub.epublish@gmail.com
 * http://code.google.com/p/epublish/
 * 
 *
 * @author      Neilin Chakrabarty <epub.epublish@gmail.com>
 * @version     0.0.1_pre_betas
 *
 * 
 * Date			Feb 21, 2010
 * 
 * 
 * Requirements	php 5.2.0 or greater
 *				zlib library
 * 
 *
 * Terms of Use	This software/code is provided free of charge.  Any
 *				use or modification of this software/code must include
 *				this header including the copyright, author, and
 *				disclaimer.
 *
 *
 * Disclaimer	This software/code is provided without any waranty 
 *				or guarantee.
 * 				Use of this software/code is done at your own risk.
 */

	class ePubContent {
		public $content;
		public $class;
		public $text;
		
		function ePubContent($content, $class="chapter", $text) {
			$this->content = $content;
			$this->class = $class;
			$this->text = $text;
		}
	}
	
	class ePubImage {
		public $content;
		public $mediatype;
		
		function ePubImage($content, $mediatype)
		{
			$this->content = $content;
			$this->mediatype = $mediatype;
		}
	}
	class ePubCreator
	{
		
		//properties
		private $css = array();
		private $images = array();
		private $fonts = array();
		private $contents = array();
		private $identifer = null;
		
		//metadata
		public $title;
		public $identifierid = "BookID";
		public $language = "en";
		public $publisher = "ePublish";
		public $author = null;
		public $sourceDate = null;
		public $producedDate = null;
		public $subject = null;
		
		//methods
		function __createNCX() {
			$output = '<?xml version="1.0" encoding="UTF-8"?>';
			$output .= '<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">';
			$output .= '<ncx version="2005-1" xml:lang="en" xmlns="http://www.daisy.org/z3986/2005/ncx/">';

			$output .= '<head>';
			$output .= '<meta name="dtb:uid" content="'.$this->identifier.'"/>';
			$output .= '<meta name="dtb:depth" content="1"/>';
			if($this->sourceDate != null)
				$output .= '<meta name ="dtb:sourcDate" content"'.$this->sourceDate.'"/>';
			if($this->producedDate != null)
				$output .= '<meta name ="dtb:sourcDate" content"'.$this->producedDate.'"/>';
			$output .= '<meta name="dtb:totalPageCount" content="0"/>';
			$output .= '<meta name="dtb:maxPageNumber" content="0"/>';
			$output .= '</head>';
			
			$output .= "<docTitle><text>$this->title</text></docTitle>";
			
			$output .= "<docAuthor><text>$this->author</text></docAuthor>";
			
			$output .= "<navMap>";
			$keys = array_keys($this->contents);
			for($i = 0; $i < count($this->contents); $i++) {
				$output .= '<navPoint class="'./*$this->contents[$keys[$i]]->class*/'chapter'.'" id="chapter1" playOrder="'.($i+1).'">';
				$output .= '<navLabel><text>'.$this->contents[$keys[$i]]->text.'</text></navLabel>';
				$output .= '<content src="'.$keys[$i].'"/>';
				$output .= '</navPoint>';
			}
			$output .= "</navMap>";
			
			$output .= "</ncx>";
			
			return $output;
		}
		
		function __createOPF() {
			$output = '<?xml version="1.0"?>';
			$output .= '<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="'.$this->identifierid.'">';

			$output .= '<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">';
			$output .= '<dc:title>'.$this->title.'</dc:title>';
			$output .= '<dc:language>'.$this->language.'</dc:language>';
			$output .= '<dc:identifier id="'.$this->identifierid.'" opf:scheme="URL">'.$this->identifier.'</dc:identifier>';
			$output .= '<dc:creator opf:file-as="'.$this->author.'" opf:role="aut">'.$this->author.'</dc:creator>';
			if($this->subject != null)
				$output .= '<dc:subject>'.$this->subject.'</dc:subject>';
			$output .= '</metadata>';
			
			$output .= '<manifest>';

			$keys = array_keys($this->contents);
			for($i = 0; $i < count($this->contents); $i++) {
				$output .= '<item id="'.strtok($keys[$i], ".").'" href="'.$keys[$i].'" media-type="applicaiton/xhtml+xml"/>';
			}

			$keys = array_keys($this->css);
			for($i = 0; $i < count($this->css); $i++) {
				$output .= '<item id="stylesheet" href="'.$keys[$i].'" media-type="text/css"/>';
			}

			$keys = array_keys($this->images);
			for($i = 0; $i < count($this->images); $i++){
				$output .= '<item id="stylesheet" href="'.$keys[$i].'" media-type="'.$images[$keys[$i]]->mediatype.'"/>';
			}
			$output .= '<item id="ncx" href="book.ncx" media-type="application/x-dtbncx+xml"/>';
			$output .= '</manifest>';
			
			$output .= '<spine toc="ncx">';
			$keys = array_keys($this->contents);
			for($i = 0; $i < count($this->contents); $i++) {
				$output .= '<itemref idref="'.strtok($keys[$i], ".").'" linear="yes"/>';
			}
			$output .= '</spine>';
			
			$output .= '</package>';
			
			return $output;
		}
		
		function addCss($localfilename, $css) {
			$this->css[$localfilename] = $css;
		}
		
		function addImage($localfilename, $image, $mediatype = "image/png") {
			$this->images[$localfilename] = new ePubImage($image, $mediatype);
		}
		
		function addContents($localfilename, $content, $text='', $class="chapter") {
			$this->contents[$localfilename] = new ePubContent($content, $class, $text);
		}
		
		function addXHTMLSnippet($localfilename, $snippet, $text='', $css=null, $class = "chapter") {
			$csscode = '';
			if($css != null) {
				$csscode = '<link rel="stylesheet" type="text/css" href="css/'.$css.'" />';
			}
			$content = '<?xml version="1.0" encoding="UTF-8" ?><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>'.$csscode.'</head><body>'.$snippet.'</body></html>';
			$this->contents[$localfilename] = new ePubContent($content, $class, $text);
		}
		
		function create($title, $id, $filename = 'book.epub') {
			$this->title = $title;
			$zip = new ZipArchive();
			
			if($zip->open($filename, ZIPARCHIVE::CREATE) != TRUE) {
				exit("Cannot open <$filename>\n");
			}
			
			$this->identifier;
			
			$zip->addEmptyDir("META-INF");
			$zip->addEmptyDir("OPS");
			$zip->addEmptyDir("OPS/css");
			$zip->addEmptyDir("OPS/images");
			
			$zip->addFromString("mimetype", "application/epub+zip");
			
			$zip->addFromString("META-INF/container.xml", '<?xml version="1.0" encoding="UTF-8" ?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
  <rootfiles>
    <rootfile full-path="OPS/book.opf" media-type="application/oebps-package+xml"/>
  </rootfiles>
</container>');

			$zip->addFromString("OPS/book.opf", $this->__createOPF());
			
			$zip->addFromString("OPS/book.ncx", $this->__createNCX());
			
			$keys = array_keys($this->css);
			for($i=0;$i<count($this->css); $i++) {
				if(file_exists($this->css[$keys[$i]]))
					$zip->addFile($this->css[$keys[$i]], "OPS/css/".$keys[$i]);
				else
					$zip->addFromString("OPS/css/".$keys[$i], $this->css[$keys[$i]]); 
			}
			
			$keys = array_keys($this->images);
			for($i=0;$i<count($this->images); $i++) {
				if(file_exists($this->images[$keys[$i]]->content))
					$zip->addFile($this->images[$keys[$i]]->content, "OPS/images/".$keys[$i]);
				else
					$zip->addFromString("OPS/images/".$keys[$i], $this->images[$keys[$i]]->content); 
			}
						
			$keys = array_keys($this->contents);;
			for($i=0;$i<count($this->contents); $i++) {
				if(file_exists($this->contents[$keys[$i]]->content)) 
					$zip->addFile($this->contents[$keys[$i]]->content, "OPS/".$keys[$i]);
				else 
					$zip->addFromString("OPS/".$keys[$i], $this->contents[$keys[$i]]->content); 
			}
				
			$zip->close();
		}
	}
?>
